package controllers

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"micro-bbs/datamodels"
	"micro-bbs/initialize"
	"micro-bbs/libs"
	"micro-bbs/services"
	"github.com/gin-gonic/gin"
	"net/http"
	"strconv"
)

type UserController struct {

	UserService services.UserInterfaceService
}

func NewUserController() *UserController {
	obj := &UserController{
		UserService: services.NewUserService(),
	}
	return obj
}


//获取用户详情页
func (this *UserController) Detail(c *gin.Context){
	idStr := c.Param("id")
	id, _ := strconv.Atoi(idStr)
	initialize.IrisLog.Infof("[用户控制器-http请求数据]-[%d]", id)

	result, err := this.UserService.GetUserInfo(int64(id))
	initialize.IrisLog.Infof("[用户控制器-userInfo返回数据]-[%s]", libs.StructToJson(result))
	if err != nil {
		c.HTML(http.StatusNotFound, "error/404.html", gin.H{"title": "404"})
		return
	}

	//获取发布的帖子
	var query datamodels.PostByQuery
	uid := int64(id)
	query.UserId = &uid
	query.Limit = 15
	postList, _ := this.UserService.GetPostByQuery(query)
	initialize.IrisLog.Infof("[用户控制器-postList返回数据]-[%s]", postList)

	//获取发布的评论
	//var query datamodels.ParamsPostCommentList
	//query.PostId = id
	//commentList, _ := this.PostService.GetPostCommentList(query)
	//initialize.IrisLog.Infof("[帖子控制器-commentList返回数据]-[%s]", libs.StructToJson(commentList))

	c.HTML(http.StatusOK, "user/detail.html", gin.H{
		"title": result.(datamodels.BbsUser).Nickname,
		"address": "bbs.100txy.com",
		"id": id,
		"data": result,
		"postData": postList,
	})
}

//获取登录用户信息
func (this *UserController) LoginInfo(c *gin.Context){
	//用户信息
	var userinfo interface{}
	//获取恭喜session
	sessionStr,err := initialize.RedisClient.Get("sso_client_login").Result()
	if err != nil || len(sessionStr) == 0{
		//panic(err)
		c.JSON(http.StatusOK, libs.ReturnJson(5004,"", gin.H{
			"userinfo": userinfo,
		}))
		return
	}
	//if len(respBytes) == 0{
	//	return nil
	//}
	tokenMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(sessionStr), &tokenMap)
	if err != nil {
		fmt.Println("Umarshal failed:", err)
		fmt.Println("sessionStr:",sessionStr)
		return
	}

	//效验token
	res,err := this.checkToken(c,tokenMap["access_token"].(string))
	if res.(map[string]interface{})["user_id"] != ""  && err == nil {
		uid, _ := strconv.ParseInt(res.(map[string]interface{})["user_id"].(string), 10, 64)
		bbsUserInfo := initialize.RedisClient.Get("member:userinfo:"+strconv.FormatInt(uid,10))
		if bbsUserInfo.Val() != ""{
			userinfoMap := make(map[string]interface{})
			err = json.Unmarshal([]byte(bbsUserInfo.Val()), &userinfoMap)
			if err != nil {
				fmt.Println("Umarshal failed:", err)
				return
			}
			//推送登录日志MQ消息
			services.NewRabbitmqService().PushLoginLog(int64(userinfoMap["id"].(float64)))
			c.JSON(http.StatusOK, libs.ReturnJson(200,"", gin.H{
				"tokenMap": tokenMap,
				"res": res,
				"userinfo": userinfoMap,
			}))
			return
		}
		user,err := this.UserService.GetUserInfoById(uid)
		fmt.Println("user:",user)
		if err != nil || user == nil {
			fmt.Println("rpc request failed:", err)
			return
		}
		//缓存
		redisUser, _ := json.Marshal(user)
		initialize.RedisClient.Set("member:userinfo:"+strconv.FormatInt(uid,10),redisUser,-1)
		userinfo = user
	}

	//推送登录日志MQ消息
	services.NewRabbitmqService().PushLoginLog(userinfo.(map[string]interface{})["id"].(int64))
	c.JSON(http.StatusOK, libs.ReturnJson(200,"", gin.H{
		"tokenMap": tokenMap,
		"res": res,
		"userinfo": userinfo,
	}))
}

//效验sso分发的access_token有效性
func (this *UserController)checkToken(c *gin.Context, oauth_token string) (interface{},error) {
	req, err := http.NewRequest(http.MethodGet, "http://ssoserver.com:9096/test", nil)
	req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	req.Header.Set("Authorization","Bearer "+oauth_token)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return "", err
	}
	fmt.Println("resp str:",string(bs))//invalid access token
	if string(bs) == "invalid access token" {
		return "", errors.New("invalid access token")
	}
	m := make(map[string]interface{})
	err = json.Unmarshal(bs, &m)
	if err != nil {
		return "", err
	}
	fmt.Println("map:", m)
	return m, nil
}

//退出sso
func (this *UserController)Logout(c *gin.Context) {
	//清除redis共享session
	initialize.RedisClient.Del("sso_client_login")
	req, err := http.NewRequest(http.MethodGet, "http://ssoserver.com:9096/logout?redirect_uri=http%3a%2f%2fssoserver.com%3a9096%2fauthorize%3fclient_id%3dtest_client_3%26response_type%3dcode%26scope%3dall%26state%3dxyz%26", nil)
	req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
	}
	//defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)

	}
	fmt.Println("resp str:",string(bs))//invalid access token
	m := make(map[string]interface{})
	err = json.Unmarshal(bs, &m)
	if err != nil {
	}
	fmt.Println("map:", m)
	c.JSON(http.StatusOK, libs.ReturnJson(200,"", gin.H{}))
}